home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Online / hsc / source / hsclib / lmessage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-02  |  16.2 KB  |  572 lines

  1. /*
  2.  * This source code is part of hsc, a html-preprocessor,
  3.  * Copyright (C) 1995-1997  Thomas Aglassinger
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20. /*
  21.  * hsclib/message.c
  22.  *
  23.  * message functions for hsc
  24.  *
  25.  * updated:  8-Oct-1997
  26.  * created: 10-Mar-1996
  27.  *
  28.  */
  29.  
  30. #define NOEXTERN_HSCLIB_MESSAGE_H
  31.  
  32. #include "hsclib/inc_base.h"
  33.  
  34. #include "ugly/returncd.h"
  35.  
  36. /*
  37.  * NOTE: see "hsclib/msgid.h" for message-id's and
  38.  *       how a message-id is build.
  39.  */
  40.  
  41. static VOID msg_tag(EXPSTR * msgstr, CONSTRPTR tagname)
  42. {
  43.     app_estr(msgstr, "tag <");
  44.     app_estr(msgstr, tagname);
  45.     app_estr(msgstr, ">");
  46. }
  47.  
  48. static VOID msg_endtag(EXPSTR * msgstr, CONSTRPTR tagname)
  49. {
  50.     app_estr(msgstr, "end tag </");
  51.     app_estr(msgstr, tagname);
  52.     app_estr(msgstr, ">");
  53. }
  54.  
  55. static VOID msg_attr(EXPSTR * msgstr, CONSTRPTR attrname)
  56. {
  57.     app_estr(msgstr, "attribute ");
  58.     app_estr(msgstr, attrname);
  59. }
  60.  
  61. static VOID msg_lazy(EXPSTR * msgstr, CONSTRPTR lazy_name)
  62. {
  63.     app_estr(msgstr, "var-list ");
  64.     app_estr(msgstr, lazy_name);
  65. }
  66.  
  67. static VOID msg_entity(EXPSTR * msgstr, CONSTRPTR entname)
  68. {
  69.     app_estr(msgstr, "entity `");
  70.     app_estr(msgstr, entname);
  71.     app_estr(msgstr, "'");
  72. }
  73.  
  74. static VOID msg_idname(EXPSTR * msgstr, CONSTRPTR idname)
  75. {
  76.     app_estr(msgstr, "id ");
  77.     app_estr(msgstr, "\"#");
  78.     app_estr(msgstr, idname);
  79.     app_estrch(msgstr, '"');
  80. }
  81.  
  82. /*
  83.  * hsc_message
  84.  *
  85.  * create message string and send it to call-back
  86.  *
  87.  * legal placeholders inside format:
  88.  *  %A ptr to HSCATTR
  89.  *  %a string for attribute-name
  90.  *  %C ptr to HSCTAG, displayed as end-tag
  91.  *  %c string to end-tag
  92.  *  %d dezimal number (LONG)
  93.  *  %E ptr to HSCENT
  94.  *  %e string to entity-name
  95.  *  %i string to id-name
  96.  *  %j string to jerk/prostitute
  97.  *  %L ptr to var-list
  98.  *  %l string to var-list
  99.  *  %q quoted string
  100.  *  %s string
  101.  *  %T ptr to HSCTAG
  102.  *  %t string for tag-name
  103.  *
  104.  * example:
  105.  * ---
  106.  *  HSCTAG *mytag;
  107.  *  STRPTR expected_tag = "dummy";
  108.  *
  109.  *  hsc_message( hp, MSG_my_tag_expected,
  110.  *               "Expected tag %T insted of %t",
  111.  *               mytag, expected_tag );
  112.  * ---
  113.  */
  114.  
  115. /* checks if filename starts with PARENT_FILE_ID */
  116. static BOOL is_child_file(STRPTR filename)
  117. {
  118.     return ((BOOL) ! strncmp(filename, PARENT_FILE_ID,
  119.                              strlen(PARENT_FILE_ID)));
  120. }
  121.  
  122. /* decides, if a message should be ignored or display */
  123. static BOOL really_display_message(HSCPRC *hp, HSCMSG_ID msg_id)
  124. {
  125.     HSCMSG_CLASS msg_class = hsc_get_msg_class(hp, msg_id);
  126.     HSCMSG_ID msg_id_unmasked = msg_id & MASK_MESSAGE;
  127.     BOOL disp_msg = TRUE;       /* function result */
  128.  
  129.     if (hp->fatal)
  130.     {
  131.  
  132.         /* oppress all messages after fatal errors */
  133.         disp_msg = FALSE;
  134.     }
  135.     else if (
  136.                 (hsc_get_msg_ignore(hp, msg_id) == ignore)
  137.                 &&
  138.                 (msg_class <= MSG_WARN)
  139.         )
  140.     {
  141.         /* oppress message if it is marked as ignored
  142.          * and it is no ERROR/FATAL message */
  143.         D(fprintf(stderr, DHL "ignore msg#%ld: ignore enabled\n",
  144.                   msg_id_unmasked));
  145.         disp_msg = FALSE;
  146.     }
  147.     else if (((msg_class == MSG_NOTE) && (hp->msg_ignore_notes))
  148.              || ((msg_class == MSG_STYLE) && (hp->msg_ignore_style))
  149.              || ((msg_class == MSG_PORT) && (hp->msg_ignore_port))
  150.         )
  151.     {
  152.         /* class should be ignored; however, if this message is set
  153.          * to enable, still display it */
  154.         if (hsc_get_msg_ignore(hp, msg_id) != enable)
  155.         {
  156.             /* oppress message if it's class is
  157.              * marked as to be ignored */
  158.             D(fprintf(stderr, DHL "ignore msg#%ld: ignore whole class (%06lx)\n",
  159.                       msg_id_unmasked, msg_class));
  160.             disp_msg = FALSE;
  161.         }
  162.         else
  163.         {
  164.             D(fprintf(stderr, DHL "enable msg#%ld: only ignore whole class (%06lx)\n",
  165.                       msg_id_unmasked, msg_class));
  166.         }
  167.     }
  168.  
  169.     return disp_msg;
  170. }
  171.  
  172. VOID hsc_message(HSCPRC * hp, HSCMSG_ID msg_id, const char *format,...)
  173. {
  174.     HSCMSG_CLASS msg_class = hsc_get_msg_class(hp, msg_id);
  175.     HSCMSG_ID msg_id_unmasked = msg_id & MASK_MESSAGE;
  176.     INFILE *msg_inpf = NULL;
  177.     STRPTR msg_fname = "unknown";
  178.     ULONG msg_x = 0;
  179.     ULONG msg_y = 0;
  180.     BOOL disp_msg = really_display_message(hp, msg_id);         /* display message? */
  181.  
  182.     if (disp_msg)
  183.     {
  184.         va_list ap;
  185.  
  186.         /* increase message-counter */
  187.         hp->msg_count++;
  188.  
  189.         /* set fatal-flag, if this is a fatal message */
  190.         if (msg_id > MSG_FATAL)
  191.             hp->fatal = TRUE;
  192.  
  193.         /* clear message buffer */
  194.         clr_estr(hp->curr_msg);
  195.  
  196.         /* create message string */
  197.         va_start(ap, format);
  198.         while (format[0])
  199.         {
  200.             if (format[0] == '%')
  201.             {
  202.                 STRPTR s = NULL;
  203.                 HSCTAG *tag = NULL;
  204.                 HSCTAG *lazy = NULL;
  205.                 HSCATTR *attr = NULL;
  206.                 HSCENT *ent = NULL;
  207.  
  208.                 format++;
  209.                 switch (format[0])
  210.                 {
  211.  
  212.                 case 'd':
  213.                     /*
  214.                      * append decimal number
  215.                      */
  216.                     app_estr(hp->curr_msg,
  217.                              long2str(va_arg(ap, LONG)));
  218.                     break;
  219.  
  220.                 case 'q':
  221.                     /*
  222.                      * append quoted string
  223.                      */
  224.                     s = va_arg(ap, STRPTR);
  225.  
  226.                     app_estrch(hp->curr_msg, '`');
  227.                     while (s[0])
  228.                     {
  229.                         switch (s[0])
  230.                         {
  231.  
  232.                         case '\n':
  233.                             app_estr(hp->curr_msg, "\\n");
  234.                             break;
  235.                         case '\"':
  236.                             app_estr(hp->curr_msg, "\\\"");
  237.                             break;
  238.                         default:
  239.                             if (s[0] < ' ')
  240.                             {
  241.                                 app_estrch(hp->curr_msg, '\\');
  242.                                 app_estr(hp->curr_msg,
  243.                                          long2str((LONG) s[0]));
  244.                                 app_estrch(hp->curr_msg, ';');
  245.                             }
  246.                             else
  247.                                 app_estrch(hp->curr_msg, s[0]);
  248.                         }
  249.                         s++;    /* process next char */
  250.                     }
  251.                     app_estrch(hp->curr_msg, '\'');
  252.  
  253.                     break;
  254.  
  255.                 case 's':
  256.                     /*
  257.                      * append simple string
  258.                      */
  259.                     app_estr(hp->curr_msg, va_arg(ap, STRPTR));
  260.                     break;
  261.  
  262.                 case 'T':
  263.                     /* append tag-pointer */
  264.                     tag = va_arg(ap, HSCTAG *);
  265.                     msg_tag(hp->curr_msg, tag->name);
  266.                     break;
  267.  
  268.                 case 't':
  269.                     /* append tag */
  270.                     msg_tag(hp->curr_msg, va_arg(ap, STRPTR));
  271.                     break;
  272.  
  273.                 case 'C':
  274.                     /* append end tag-pointer */
  275.                     tag = va_arg(ap, HSCTAG *);
  276.                     msg_endtag(hp->curr_msg, tag->name);
  277.                     break;
  278.  
  279.                 case 'c':
  280.                     /* append end tag */
  281.                     msg_endtag(hp->curr_msg, va_arg(ap, STRPTR));
  282.                     break;
  283.  
  284.                 case 'A':
  285.                     /* append attribute-pointer */
  286.                     attr = va_arg(ap, HSCATTR *);
  287.                     msg_attr(hp->curr_msg, attr->name);
  288.                     break;
  289.  
  290.                 case 'a':
  291.                     /* append attribute */
  292.                     msg_attr(hp->curr_msg, va_arg(ap, STRPTR));
  293.                     break;
  294.  
  295.                 case 'E':
  296.                     /* append entity-pointer */
  297.                     ent = va_arg(ap, HSCENT *);
  298.                     msg_entity(hp->curr_msg, ent->name);
  299.                     break;
  300.  
  301.                 case 'e':
  302.                     /* append entity */
  303.                     msg_entity(hp->curr_msg, va_arg(ap, STRPTR));
  304.                     break;
  305.  
  306.                 case 'i':
  307.                     /* append ID */
  308.                     msg_idname(hp->curr_msg, va_arg(ap, STRPTR));
  309.                     break;
  310.  
  311.                 case 'j':
  312.                     /* append jerk/prostitute */
  313.                     if (hp->prostitute)
  314.                     {
  315.                         app_estr(hp->curr_msg, "prostitutes");
  316.                     }
  317.                     else
  318.                     {
  319.                         app_estr(hp->curr_msg, "jerks");
  320.                     }
  321.                     break;
  322.  
  323.                 case 'L':
  324.                     /* append var-list-pointer */
  325.                     lazy = va_arg(ap, HSCTAG *);
  326.                     msg_lazy(hp->curr_msg, lazy->name);
  327.                     break;
  328.  
  329.                 case 'l':
  330.                     /* append var-list */
  331.                     msg_lazy(hp->curr_msg, va_arg(ap, STRPTR));
  332.                     break;
  333.  
  334.                 default:
  335.                     /*
  336.                      * append unknown
  337.                      */
  338.                     app_estrch(hp->curr_msg, '%');
  339.                     if (format[0] && (format[0] != '%'))
  340.                     {
  341.                         app_estrch(hp->curr_msg, '%');
  342.                         format--;
  343.                     }
  344.                     break;
  345.                 }
  346.             }
  347.             else
  348.             {
  349.                 app_estrch(hp->curr_msg, format[0]);
  350.             }
  351.  
  352.             if (format[0])
  353.             {
  354.                 format++;
  355.             }
  356.         }
  357.         va_end(ap);
  358.  
  359.         /* evaluate message position */
  360.         if (hp->inpf)
  361.         {
  362.             msg_inpf = hp->inpf;
  363.  
  364.             msg_fname = infget_fname(msg_inpf);
  365.  
  366.             /* use parent file for position? */
  367.             if (is_child_file(msg_fname))
  368.             {
  369.                 DLNODE *nd = dll_first(hp->inpf_stack);
  370.  
  371.                 msg_inpf = NULL;
  372.                 msg_fname = NULL;
  373.  
  374.                 if (nd)
  375.                     do
  376.                     {
  377.                         D(fprintf(stderr, DHL "skip parent file `%s'\n", msg_fname));
  378.  
  379.                         /* use position of file on stack */
  380.                         msg_inpf = (INFILE *) dln_data(nd);
  381.                         msg_fname = infget_fname(msg_inpf);
  382.                         nd = dln_next(nd);
  383.                     }
  384.                     while (nd && is_child_file(msg_fname));
  385.             }
  386.  
  387.             if (msg_inpf)
  388.             {
  389.                 msg_x = infget_wx(msg_inpf) + 1;
  390.                 msg_y = infget_wy(msg_inpf) + 1;
  391.             }
  392.             else
  393.             {
  394.                 msg_fname = "hsc-internal.hsc";
  395.                 msg_x = 0;
  396.                 msg_y = 0;
  397.             }
  398.         }
  399.         else
  400.         {
  401.             msg_fname = NULL;
  402.             msg_x = 0;
  403.             msg_y = 0;
  404.         }
  405.  
  406. #if 0                           /* TODO: remove */
  407.         fprintf(stderr, "*** msg_id    = %06lx\n", msg_id);
  408.         fprintf(stderr, "*** msg_class = %06lx\n", msg_class);
  409. #endif
  410.         /* send message via callback */
  411.         if (hp->CB_message)
  412.  
  413.             (*(hp->CB_message))
  414.                 (hp,
  415.                  msg_class, msg_id_unmasked,
  416.                  msg_fname, msg_x, msg_y,
  417.                  estr2str(hp->curr_msg)
  418.                 );
  419.  
  420.         /* process nested files */
  421.         if (hp->CB_message_ref)
  422.         {
  423.             DLNODE *nd = dll_first(hp->inpf_stack);
  424.  
  425.             while (nd)
  426.             {
  427.                 msg_inpf = dln_data(nd);
  428.                 msg_fname = infget_fname(msg_inpf);
  429.                 msg_x = infget_wx(msg_inpf) + 1;
  430.                 msg_y = infget_wy(msg_inpf) + 1;
  431.  
  432.                 (*(hp->CB_message_ref))
  433.                     (hp,
  434.                      msg_class, msg_id_unmasked,
  435.                      msg_fname, msg_x, msg_y,
  436.                      ""
  437.                     );
  438.  
  439.                 nd = dln_next(nd);
  440.             }
  441.         }
  442.     }
  443.     else
  444.     {
  445.         D(fprintf(stderr, DHL "suppressed msg#%ld\n", msg_id_unmasked));
  446.     }
  447. }
  448.  
  449. /*
  450.  *-------------------------------------
  451.  * often occurable errors & messages
  452.  *-------------------------------------
  453.  */
  454.  
  455. VOID hsc_msg_eof(HSCPRC * hp, STRPTR descr)
  456. {
  457.     STRPTR eoftxt = "unexpected end of context";
  458.  
  459.     if (descr)
  460.     {
  461.         hsc_message(hp, MSG_UNEX_EOF, "%s (%s)", eoftxt, descr);
  462.     }
  463.     else
  464.     {
  465.         hsc_message(hp, MSG_UNEX_EOF, "%s", eoftxt);
  466.     }
  467. }
  468.  
  469. VOID hsc_msg_illg_whtspc(HSCPRC * hp)
  470. {
  471.     hsc_message(hp, MSG_ILLG_WHTSPC, "illegal white space");
  472. }
  473.  
  474. VOID hsc_msg_stripped_tag(HSCPRC * hp, HSCTAG * tag, STRPTR why)
  475. {
  476.     if (why)
  477.     {
  478.         hsc_message(hp, MSG_TAG_STRIPPED,
  479.                     "stripped tag %T (%s)", tag, why);
  480.     }
  481.     else
  482.     {
  483.         hsc_message(hp, MSG_TAG_STRIPPED,
  484.                     "stripped tag %T", tag);
  485.     }
  486. }
  487.  
  488. VOID hsc_msg_unkn_attr_ref(HSCPRC * hp, STRPTR attr)
  489. {
  490.     hsc_message(hp, MSG_UNKN_ATTR_REF,
  491.                 "unknown %a", attr);
  492. }
  493.  
  494. VOID hsc_msg_unkn_attr_tag(HSCPRC * hp, STRPTR attr, STRPTR tag)
  495. {
  496.     hsc_message(hp, MSG_UNKN_ATTR_TAG,
  497.                 "unknown %a for %t", attr, tag);
  498. }
  499.  
  500. VOID hsc_msg_unkn_attr_macro(HSCPRC * hp, STRPTR attr, STRPTR macro)
  501. {
  502.     hsc_message(hp, MSG_UNKN_ATTR_MACRO,
  503.                 "unknown %a for %t", attr, macro);
  504. }
  505.  
  506.  
  507. #if 1                           /* TODO: get rid of this */
  508. VOID hsc_msg_eol(HSCPRC * hp)
  509. {
  510.     hsc_message(hp, MSG_UNEX_EOL,
  511.                 "unexpected end of line");
  512. }
  513. #endif
  514.  
  515. VOID hsc_msg_noinput(HSCPRC * hp, STRPTR filename)
  516. {
  517.     hsc_message(hp, MSG_NO_INPUT,
  518.                 "can not open %q for input: %s",
  519.                 filename, strerror(errno));
  520. }
  521.  
  522. VOID hsc_msg_nouri(HSCPRC * hp, STRPTR filename, STRPTR uriname, STRPTR note)
  523. {
  524.     if (note)
  525.     {
  526.         hsc_message(hp, MSG_NO_URIPATH,
  527.                     "file %q for URI %q not found (%s)",
  528.                     filename, uriname, note);
  529.     }
  530.     else
  531.     {
  532.         hsc_message(hp, MSG_NO_URIPATH,
  533.                     "file %q for URI %q not found",
  534.                     filename, uriname);
  535.     }
  536. }
  537.  
  538. /*
  539.  * show up enforcer hit
  540.  */
  541. VOID enforcerHit(VOID)
  542. {
  543. #ifndef AMIGA
  544.     fputs("WORD-WRITE to  00000000        data=0000       PC: 0325B854\n"
  545.           "USP:  034735C8 SR: 0004 SW: 0729  (U0)(-)(-)  TCB: 03349A28\n"
  546.         "Name: \"Shell Process\"  CLI: \"hsc\"  Hunk 0000 Offset 00000074\n"
  547.           "\n"
  548.           "LONG-READ from AAAA4444                        PC: 0325B858\n"
  549.           "USP:  034735C8 SR: 0015 SW: 0749  (U0)(F)(-)  TCB: 03349A28\n"
  550.         "Name: \"Shell Process\"  CLI: \"hsc\"  Hunk 0000 Offset 00000078\n"
  551.           "\n"
  552.           "BYTE-WRITE to  00000101        data=11         PC: 0325B862\n"
  553.           "USP:  034735C8 SR: 0010 SW: 0711  (U0)(F)(D)  TCB: 03349A28\n"
  554.         "Name: \"Shell Process\"  CLI: \"hsc\"  Hunk 0000 Offset 00000082\n"
  555.           "\n"
  556.           "LONG-WRITE to  00000102        data=00000000   PC: 0325B86A\n"
  557.           "USP:  034735C8 SR: 0014 SW: 0709  (U0)(-)(D)  TCB: 03349A28\n"
  558.         "Name: \"Shell Process\"  CLI: \"hsc\"  Hunk 0000 Offset 0000008A\n"
  559.           "\n"
  560.           "Alert !! Alert 35000000     TCB: 03349A28     USP: 034735C4\n"
  561.           "Data: 00000000 DDDD1111 DDDD2222 DDDD3333 0325B802 DDDD5555 DDDD6666 35000000\n"
  562.           "Addr: AAAA0000 AAAA1111 AAAA2222 AAAA3333 AAAA4444 0325B802 00200810 --------\n"
  563.           "Stck: 0325B878 00000000 00FA06D6 00010000 0334A40C 03F46630 00AC4C20 00000000\n",
  564.           stderr);
  565.     /* crash machine by making fun of writing bullshit into function code
  566.      * (it must have been a complete idiot who designed a language which
  567.      * allows code like the one you can read below) */
  568.     strcpy((STRPTR) hsc_message, "die for oil, sucker");
  569.     exit(RC_FAIL);              /* just for the case we are still there.. */
  570. #endif
  571. }
  572.